package com.jxpanda.spring.module.auth.core.authentication.strategy;

import com.jxpanda.spring.module.auth.core.OAuth2StrategyResolver;
import com.jxpanda.spring.module.auth.core.authentication.token.CollaborativeAuthenticationToken;
import com.jxpanda.spring.module.auth.core.authentication.token.UserDetailsAuthenticationToken;
import com.jxpanda.spring.module.auth.endpoint.OAuth2Request;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import reactor.core.publisher.Mono;

public class CollaborativeReactiveAuthenticationOAuth2StrategyResolver extends OAuth2StrategyResolver<CollaborativeReactiveAuthenticationStrategy> {

    public <U extends UserDetails> Mono<UserDetailsAuthenticationToken<U>> resolve(CollaborativeAuthenticationToken authenticationToken) {
        // 从ClientRegistration中获取授权类型
        OAuth2Request oAuth2Request = authenticationToken.getOAuth2Request();
        return selectStrategy(oAuth2Request.getClientId(), oAuth2Request.getGrantType())
                .flatMap(strategy -> strategy.<U>resolve(authenticationToken))
                .filter(AbstractAuthenticationToken::isAuthenticated)
                // 认证成功后清除凭证，避免泄露
                .doOnNext(AbstractAuthenticationToken::eraseCredentials)
                .switchIfEmpty(Mono.error(new IllegalArgumentException("Authentication failed")));
    }

}
